package com.kitty.game.fight.model;

import com.kitty.game.skill.model.RoleSkill;
import com.kitty.game.fight.bean.Fight;
import com.kitty.game.fight.bean.FightObject;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.fight.SkillConst;
import com.kitty.game.fight.artifact.passive.ArtifactType;
import com.kitty.game.fight.book.BookSkillProcessor;
import com.kitty.game.fight.pet.PetSkillProcessor;
import com.kitty.game.fight.service.FightMessageService;
import com.kitty.game.fight.util.FightMessageUtil;
import com.kitty.game.fight.util.FightRateUtil;
import com.kitty.game.fight.service.CountService;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 本次技能释放的动作，包含所有的命中单位
 */
public class SkillAction {

    private Fight fight;

    private FightObject effector;

    private List<BattleUnit> battleUnits;

    private RoleSkill skill;

    private List<Integer> skillTargets;

    public SkillAction(Fight fight, FightObject effector, RoleSkill roleSkill) {
        this.effector = effector;
        this.fight = fight;
        this.skill = roleSkill;
    }


    public List<Integer> pickUpTargets() {
        int targetNum = SpringUtils.getSkillService().getSkillTargetNum(skill);
        skillTargets = SpringUtils.getFightService().getTargetListNew(effector, targetNum, fight);
        return skillTargets;
    }


    /**
     * 执行法术攻击
     */
    public void doMagicEffect() {
        /**必杀*/
        boolean isStunt = FightRateUtil.calcMagicStuntRate(effector, skill);
        /**破防*/
        boolean isPenetrate = FightRateUtil.calcMagicPenetrateRate(effector, skill);
        int targetAction = 1;
        /**默认法攻为2*/
        int myAction = 2;

        FightObject targetObject = fight.queryFightObject(effector.getTargetId());
        if (targetObject == null || targetObject.isFallDown()) {
            if (skillTargets.size() > 0) {
                effector.setTargetId(skillTargets.get(0));
                targetObject = fight.queryFightObject(effector.getTargetId());
            }
        }
        if (targetObject != null && targetObject.isFrozen()) { /**如果目标在冰冻状态 那么目标不能做任何动作 否则会卡客户端*/
            targetAction = 2;
        }
        if (isStunt) {/**如果必杀了 + 32*/
            myAction += 32;
        }
        if (isPenetrate) { /**如果破防了 + 8192*/
            myAction += 8192;
        }

        FightMessageService fightMessageService = SpringUtils.getFightMessageService();

        boolean hasEnemy = false;
        for (Integer targetId : skillTargets) {
            FightObject target = fight.queryFightObject(targetId);
            if (!fight.isSameSide(effector, target)) {
                hasEnemy = true;
                break;
            }
        }

        int hitTimes = 1;

        // 避免对己方的增益法术(例如乾坤罩)触发天书
        if (hasEnemy) {
            if (BookSkillProcessor.attackTrigger(fight, effector, null, BookSkillProcessor.XIU_LUO)) {
                hitTimes = 2;
            }
        }

        for (int i = 0; i < hitTimes; i++) {
            FightMessageUtil.sendFightPackage(fight, fightMessageService.combatAcceptHit(effector, targetAction, myAction, 0));
            /**技能多目标动画*/
            FightMessageUtil.sendFightPackage(fight, fightMessageService.skillAction(fight, effector.getId(), skillTargets, myAction, skill.getType() == 146));

            for (Integer targetId : skillTargets) {
                FightObject target = fight.queryFightObject(targetId);
                if (target == null) {
                    continue;
                }

                /**这个不应该无条件跳过  木系的辅助技能 舍身取义可以对倒地目标释放*/
                List<Integer> woodAssistSkills = Arrays.asList(81, 82, 83, 84, 85, SkillConst.SKILL_SHE_SHEN);
                if (target.isFallDown() && !woodAssistSkills.contains(effector.getSkillId())) {
                    continue;
                }
                BattleUnit battleUnit = new BattleUnit(fight, effector, target, skill, skill.getLevel());
                battleUnit.setStunt(isStunt);
                battleUnit.setPenetrate(isPenetrate);
                battleUnit.triggerMagic();
            }
        }


        //舍命一击 舍身取义 等类似技能
        if (effector.isFallDown()) {
            FightMessageUtil.sendFightPackage(fight, fightMessageService.fallDown(effector.getId(), 1));
            fight.onActorDie(effector);
        }

        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(effector.getId()));
    }

    public void setSkillTargets(List<Integer> skillTargets) {
        this.skillTargets = skillTargets;
    }

    public void liPoEffect() {
        boolean isStunt = false;
        boolean isPenetrate = false;
        int doubleHit = 1;
        boolean triggerDipper = false;
        Random random = new Random();
        if (effector.isPlayer()) {
            triggerDipper = (boolean) ArtifactType.DIPPER.getEffect().trigger(fight, effector);
        }
        if (!triggerDipper) {
            if ((random.nextInt(100) + 1) <= (effector.isPlayer() ? effector.getRole().getStuntRate() : 10)) {// 物理必杀
                isStunt = true;
            }
            if ((random.nextInt(100) + 1) <= (effector.isPlayer() ? effector.getRole().getPenetrateRate() : 0)) {// 破防率
                isPenetrate = true;
            }
        }
        if (!triggerDipper && !isStunt) {
            if (effector.isPlayer() && (random.nextInt(100) + 1) <= effector.getRole().getDoubleHitRate()) {
                doubleHit = effector.getRole().getDoubleHit();
                if (doubleHit <= 0) {
                    doubleHit = 2;
                }
                if (doubleHit >=9){
                    doubleHit=9;
                }
            }
        }
        int targetAction = 1;
        /**默认法攻为2 物攻1 */
        int myAction = 1;
        FightObject mainTarget = fight.queryFightObject(effector.getTargetId());
        if (mainTarget == null || mainTarget.isFallDown() || mainTarget.isASide() == effector.isASide()) {
            mainTarget = fight.queryFightObject(skillTargets.get(0));
            /**如果目标ID为0的情况下 就会出现在屏幕外面去了*/
            effector.setTargetId(mainTarget.getId());
        }
        double damageSel = 0;
        int damageSelRate = 0;
        if (mainTarget.isPlayer()) {
            damageSelRate = mainTarget.getRole().getDamageSelRate();
        }
        //未躲避 ,未反伤 计算反震率。
        boolean isDamage = damageSelRate >= random.nextInt(100) + 1;
        mainTarget.pushTempCache("damage", isDamage);
        if (mainTarget.isFrozen()) { /**如果目标在冰冻状态 那么目标不能做任何动作 否则会卡客户端*/
            targetAction = 2;
        }
        if (isStunt) {/**如果必杀了 + 32*/
            myAction += 32;
        }
        if(isDamage){
            myAction += 8;
        }
        if (isPenetrate) { /**如果破防了 + 8192*/
            myAction += 8192;
        }

        FightMessageService fightMessageService = SpringUtils.getFightMessageService();
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionStart(fight.getRound(), effector));
        FightMessageUtil.sendFightPackage(fight, fightMessageService.updateObjectInfo(effector));
        FightMessageUtil.sendFightPackage(fight, fightMessageService.fightShouting(effector, "法攻"));

        if (triggerDipper) {
            ArtifactType.DIPPER.getEffect().broadCast(fight, effector);
        }

        Map<Integer, Integer> hurtMap = new HashMap<>();
        CountService countService = SpringUtils.getBean(CountService.class);
        for (Integer targetId : skillTargets) {
            FightObject target = fight.queryFightObject(targetId);
            if (target == null || target.isFallDown()) {
                continue;
            }
            int hurt = countService.countHurt(fight, effector, target, isPenetrate);
            if (isStunt) {
                hurt *= 1.5;
            }
            if (triggerDipper) {
                hurt *= 2.5;
            }
            if (hurt > target.getCurrLife()) {
                hurt = target.getCurrLife();
            }
            hurtMap.put(targetId, hurt);
        }
        /**主目标躲避状态*/
        int tempDodge = mainTarget.getExtraDodge();
        if (mainTarget.isPlayer()) {
            tempDodge += mainTarget.getRole().getDodge();
        }
        boolean mainTargetDodge = tempDodge >= new Random().nextInt(100) + 1;
        mainTarget.pushTempCache("dodge", mainTargetDodge);
        if(mainTargetDodge){
            targetAction = 0;
        }
        for (int i = 0; i < doubleHit; i++) {
            if (i > 0) {
                /**大于0代表是连击 改为连击动作*/
                myAction = 17;
                if (isPenetrate) { /**如果破防了 + 8192*/
                    myAction += 8192;
                }
            }
            FightMessageUtil.sendFightPackage(fight, fightMessageService.combatAcceptHit(effector, targetAction, myAction, 0));
            FightMessageUtil.sendFightPackage(fight, fightMessageService.liPoAction(fight, effector.getId(), skillTargets, myAction, mainTarget.getId()));
            for (Integer targetId : skillTargets) {
                FightObject target = fight.queryFightObject(targetId);
                if (target == null || target.isFallDown()) {
                    continue;
                }
                int hurt = new Double(hurtMap.get(targetId) / (Math.pow(2, i))).intValue();
                boolean dodge = target.popTempCache("dodge", false);
                if (dodge) {
                    hurt = 0;
                }
                BattleUnit battleUnit = new BattleUnit(fight, effector, target, skill, skill.getLevel());
                battleUnit.setStunt(isStunt);
                battleUnit.setPenetrate(isPenetrate);
                battleUnit.setSkillTargets(skillTargets);
                // 游说伤害减少
                hurt = (int) PetSkillProcessor.queryProcessor(SkillConst.SKILL_YOU_SHUO).effect(fight, effector, target, hurt);
                battleUnit.setHurt(hurt);
                battleUnit.afterUseLiPo(dodge,targetId,mainTarget.getId());
            }

            /**如果主目标倒下或者死亡 或者我倒下 或者主目标躲避了 连击应该终止*/
            if (mainTarget.isFallDown() || effector.isFallDown() || mainTargetDodge) {
                break;
            }
        }
        mainTarget.popTempCache("damage", false);
        FightMessageUtil.sendFightPackage(fight, fightMessageService.doActionEnd(effector.getId()));
    }

}
